package com.scm.service.impl;

import com.scm.common.core.domain.entity.SysUser;
import com.scm.common.exception.ServiceException;
import com.scm.common.utils.DateUtils;
import com.scm.common.utils.TOTransferHelper;
import com.scm.dto.req.inventory.CreateInventoryOutByOrderReq;
import com.scm.dto.req.inventory.SaveScmInventoryInReq;
import com.scm.dto.req.inventory.SaveScmInventoryOutReq;
import com.scm.dto.resp.invent.QueryInventoryInPageResp;
import com.scm.dto.resp.invent.QueryInventoryOutPageResp;
import com.scm.dto.resp.invent.ScmInventoryOutDetailDo;
import com.scm.dto.resp.invent.ScmInventoryStashProductDo;
import com.scm.persist.model.*;
import com.scm.persist.mybatis.ScmInventoryInDetailMapper;
import com.scm.persist.mybatis.ScmInventoryInMapper;
import com.scm.persist.mybatis.ScmInventoryOutDetailMapper;
import com.scm.persist.mybatis.ScmInventoryOutMapper;
import com.scm.service.IScmInventoryOutService;
import com.scm.service.IScmInventoryStashProductService;
import org.apache.commons.compress.utils.Lists;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Random;

@Service
public class ScmInventoryOutServiceImpl implements IScmInventoryOutService {


    @Autowired
    private ScmInventoryOutMapper scmInventoryOutMapper;

    @Autowired
    private ScmInventoryOutDetailMapper scmInventoryOutDetailMapper;

    @Autowired
    private IScmInventoryStashProductService inventoryStashProductService;


    /**
     * 查询库存-出库信息
     *
     * @param id 库存-出库信息主键
     * @return 库存-出库信息
     */
    @Override
    public ScmInventoryOut selectScmInventoryOutById(Long id)
    {
        return scmInventoryOutMapper.selectByPrimaryKey(id);
    }

    /**
     * 查询库存-出库信息列表
     *
     * @param scmInventoryout 库存-出库信息
     * @return 库存-出库信息
     */
    @Override
    public QueryInventoryOutPageResp selectScmInventoryOutList(ScmInventoryOut scmInventoryout , Integer start, Integer size)
    {
        ScmInventoryOutExample example = new ScmInventoryOutExample();

        int count = scmInventoryOutMapper.countByExample(example);
        List<ScmInventoryOut> list = Lists.newArrayList();
        if(count>0){

            RowBounds rowBounds = new RowBounds(start,size);

            list =  scmInventoryOutMapper.selectByExampleWithRowbounds(example,rowBounds);
        }
        return QueryInventoryOutPageResp.builder().total(count).list(list).build();
    }

    /**
     * 新增库存-出库信息
     *
     * @param scmInventoryOut 库存-出库信息
     * @return 结果
     */
    @Override
    public int insertScmInventoryOut(ScmInventoryOut scmInventoryOut)
    {
        return 1;
    }

    /**
     * 修改库存-出库信息
     *
     * @param scmInventoryOut 库存-出库信息
     * @return 结果
     */
    @Override
    public int updateScmInventoryOut(ScmInventoryOut scmInventoryOut)
    {
        return scmInventoryOutMapper.updateByPrimaryKeySelective(scmInventoryOut);
    }

    /**
     * 批量删除库存-出库信息
     *
     * @param id 需要删除的库存-出库信息主键
     * @return 结果
     */
    @Override
    public int deleteScmInventoryOutById(String id)
    {
        ScmInventoryOut scmInventoryOut = this.selectScmInventoryOutById(Long.valueOf(id));

        if("beInStorage".equals(scmInventoryOut.getStatus())){
            throw new ServiceException("已出库单据不能删除！");
        }
        scmInventoryOut.setStatus("del");
        this.updateScmInventoryOut(scmInventoryOut);
        return 1;
    }

    /**
     * 删除库存-出库信息信息
     *
     * @param id 库存-出库信息主键
     * @return 结果
     */
    @Override
    public int deleteScmInventoryOutById(Long id)
    {
        return scmInventoryOutMapper.deleteByPrimaryKey(id);
    }


    @Override
    public List<ScmInventoryOutDetailDo> selectScmInventoryOutDetailListList(Long inventoryOutId) {

        ScmInventoryOutDetailExample example = new ScmInventoryOutDetailExample();
        example.createCriteria().andInventoryOutIdEqualTo(inventoryOutId);
        List<ScmInventoryOutDetail> list = scmInventoryOutDetailMapper.selectByExample(example);

        if(CollectionUtils.isEmpty(list)){
            return Lists.newArrayList();
        }
        List<ScmInventoryOutDetailDo> inventoryOutDetailList = TOTransferHelper.trans2TO(list, ScmInventoryOutDetailDo.class);
        for (ScmInventoryOutDetailDo scmInventoryOutDetailDo : inventoryOutDetailList) {

            scmInventoryOutDetailDo.setOutCount(scmInventoryOutDetailDo.getProductCount());
            ScmInventoryStashProductDo inventoryStashProductDo = inventoryStashProductService.getStashProductById(scmInventoryOutDetailDo.getStashProductId());
            scmInventoryOutDetailDo.setAvailableCount(inventoryStashProductDo.getAvailableCount()+scmInventoryOutDetailDo.getProductCount());
        }
        return inventoryOutDetailList;
    }

    @Transactional
    @Override
    public synchronized  int saveScmInventoryOut(SaveScmInventoryOutReq req, SysUser sysUser) {

        ScmInventoryOut scmInventoryOut = req.getScmInventoryOut();
        scmInventoryOut.setTenantId(sysUser.getTenantId());
        scmInventoryOut.setCreateTime(System.currentTimeMillis());
        scmInventoryOut.setCreateUser(String.valueOf(sysUser.getUserId()));
        scmInventoryOut.setStatus("pending");
        int i = scmInventoryOutMapper.insertSelective(scmInventoryOut);

        List<ScmInventoryOutDetail> list = req.getScmInventoryOutDetailList();

        //锁库存
        inventoryStashProductService.lockStashProductByInsert(list);

        if(!CollectionUtils.isEmpty(list)){
            for (ScmInventoryOutDetail scmInventoryOutDetail : list) {
                scmInventoryOutDetail.setTenantId(sysUser.getTenantId());
                scmInventoryOutDetail.setInventoryOutId(scmInventoryOut.getId());
                scmInventoryOutDetail.setCreateTime(System.currentTimeMillis());
                scmInventoryOutDetail.setCreateUser(String.valueOf(sysUser.getUserId()));

                ScmInventoryStashProductDo scmInventoryStashProductDo = inventoryStashProductService.getStashProductById(scmInventoryOutDetail.getStashProductId());
                scmInventoryOutDetail.setStashId(scmInventoryStashProductDo.getStashId());
                scmInventoryOutDetail.setStashName(scmInventoryStashProductDo.getStashName());
                scmInventoryOutDetail.setProductId(scmInventoryStashProductDo.getProductId());
                scmInventoryOutDetail.setProductCode(scmInventoryStashProductDo.getProductCode());
                scmInventoryOutDetail.setProductName(scmInventoryStashProductDo.getProductName());
                scmInventoryOutDetail.setProductSpec(scmInventoryStashProductDo.getProductSpec());
                scmInventoryOutDetail.setProductUnit(scmInventoryStashProductDo.getProductUnit());
            }

            scmInventoryOutDetailMapper.batchInsert(list);
        }

        return 1;
    }

    private List<ScmInventoryOutDetail> getScmInventoryOutDetailList(Long inventoryOutId){

        ScmInventoryOutDetailExample example = new ScmInventoryOutDetailExample();
        example.createCriteria().andInventoryOutIdEqualTo(inventoryOutId);
        List<ScmInventoryOutDetail> list = scmInventoryOutDetailMapper.selectByExample(example);
        return list;
    }

    @Transactional
    @Override
    public synchronized int updateScmInventoryOut(SaveScmInventoryOutReq req, SysUser sysUser) {

        ScmInventoryOut scmInventoryOut = req.getScmInventoryOut();
        scmInventoryOut.setTenantId(sysUser.getTenantId());
        scmInventoryOut.setUpdateTime(System.currentTimeMillis());
        scmInventoryOut.setUpdateUser(String.valueOf(sysUser.getUserId()));
        int i = scmInventoryOutMapper.updateByPrimaryKeySelective(scmInventoryOut);

        //获取单据更新的库存商品信息
        List<ScmInventoryOutDetail> list = req.getScmInventoryOutDetailList();

        //获取单据之前库存商品信息
        List<ScmInventoryOutDetail> oldList = getScmInventoryOutDetailList(scmInventoryOut.getId());

        //锁定商品库存信息
        inventoryStashProductService.lockStashProductByUpdate(oldList,list);


        ScmInventoryOutDetailExample example = new ScmInventoryOutDetailExample();
        example.createCriteria().andInventoryOutIdEqualTo(scmInventoryOut.getId());
        scmInventoryOutDetailMapper.deleteByExample(example);

        if(!CollectionUtils.isEmpty(list)){
            for (ScmInventoryOutDetail scmInventoryOutDetail : req.getScmInventoryOutDetailList()) {

                scmInventoryOutDetail.setTenantId(sysUser.getTenantId());
                scmInventoryOutDetail.setInventoryOutId(scmInventoryOut.getId());
                scmInventoryOutDetail.setCreateTime(System.currentTimeMillis());
                scmInventoryOutDetail.setCreateUser(String.valueOf(sysUser.getUserId()));

                ScmInventoryStashProductDo scmInventoryStashProductDo = inventoryStashProductService.getStashProductById(scmInventoryOutDetail.getStashProductId());
                scmInventoryOutDetail.setStashId(scmInventoryStashProductDo.getStashId());
                scmInventoryOutDetail.setStashName(scmInventoryStashProductDo.getStashName());
                scmInventoryOutDetail.setProductId(scmInventoryStashProductDo.getProductId());
                scmInventoryOutDetail.setProductCode(scmInventoryStashProductDo.getProductCode());
                scmInventoryOutDetail.setProductName(scmInventoryStashProductDo.getProductName());
                scmInventoryOutDetail.setProductSpec(scmInventoryStashProductDo.getProductSpec());
                scmInventoryOutDetail.setProductUnit(scmInventoryStashProductDo.getProductUnit());
            }

            scmInventoryOutDetailMapper.batchInsert(list);
        }

        return 0;
    }

    @Transactional
    @Override
    public synchronized int confirmScmInventoryOut(Long inventoryOutId, SysUser sysUser) {

        List<ScmInventoryOutDetail> detailList = getScmInventoryOutDetailList(inventoryOutId);

        //入库
        if(CollectionUtils.isEmpty(detailList)){
            return 1;
        }

        for (ScmInventoryOutDetail scmInventoryOutDetail : detailList) {
            inventoryStashProductService.saveStashProductByOut(sysUser.getTenantId(),scmInventoryOutDetail);
        }
        //todo 确认出库是否需要上传相关凭证
        //todo操作记录
        ScmInventoryOut scmInventoryOut = scmInventoryOutMapper.selectByPrimaryKey(inventoryOutId);
        scmInventoryOut.setStatus("success");
        int i = scmInventoryOutMapper.updateByPrimaryKey(scmInventoryOut);

        if(i==0){
            throw new RuntimeException("库存更新失败，请重试或联系系统管理员");
        }
        return 1;


    }

    @Override
    public int createScmInventoryOutByOrder(SysUser sysUser, CreateInventoryOutByOrderReq req) {


        ScmInventoryOut scmInventoryOut = new ScmInventoryOut();
        scmInventoryOut.setTenantId(sysUser.getTenantId());

        Random random = new Random();
        int randomNumber = random.nextInt(900000) + 100000;

        scmInventoryOut.setCode(DateUtils.dateTime()+randomNumber);
        scmInventoryOut.setName("销售单转出库,订单号:"+req.getOrderId());
        scmInventoryOut.setOutDatetime(System.currentTimeMillis());
        scmInventoryOut.setOutDatetimeStr(DateUtils.getDate());

        scmInventoryOut.setOrderId(String.valueOf(req.getOrderId()));
        scmInventoryOut.setSalesmanId(sysUser.getUserId());
        scmInventoryOut.setSalesmanName(sysUser.getUserName());
        scmInventoryOut.setRemark("");
        scmInventoryOut.setCreateTime(System.currentTimeMillis());
        scmInventoryOut.setCreateUser(String.valueOf(sysUser.getUserId()));

        SaveScmInventoryOutReq saveScmInventoryOutReq = new SaveScmInventoryOutReq();
        saveScmInventoryOutReq.setScmInventoryOut(scmInventoryOut);
        saveScmInventoryOutReq.setScmInventoryOutDetailList(req.getDetails());

        saveScmInventoryOut(saveScmInventoryOutReq,sysUser);
        return 1;
    }


}
